import React from 'react';
import { Button, Space, Spin, Tooltip, message } from 'antd';
import { FolderOutlined, FileExcelOutlined, FolderAddOutlined, FileAddOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons';
import _ from 'lodash';

import ReportDirDialog from './ReportDirDialog'
import ReportFileDialog from './ReportFileDialog'
import MyTree from './MyTree'

import SparkChannel, { EE } from '../ipc/sparkchannel'
import { ReportType } from '../core/common'
import { MyModal } from '../util/utils'

function buildTreeNode(catalog) {
  const typeNodes = [];
  for (const t of ReportType.REPORT_TYPES) {
    const type2 = t.value;

    let n = {
      title: t.label,
      key: `${catalog.id}-${type2}`,
      directoryId: catalog.id,
      reportType: t.id,
    };
    typeNodes.push(n);
    typeNodes[type2] = n;
  }

  if (catalog.report_list) {
    for (let report of catalog.report_list) {
      let type2 = ReportType.getReportTypeValue(report.report_type);
      // console.log('add', report, 'to', type2);
      report.report_type2 = type2; // REAL, DAY, ...
      let node = typeNodes[type2];
      if (!node.children) {
        node.children = [];
      }
      node.children.push({
        title: report.report_name,
        key: `REPORT-${report.id}`,
        icon: <FileExcelOutlined />,
        data: report,
        directoryId: catalog.id,
        reportType: report.report_type,
      },);
    }
  }

  const node = {
    title: catalog.directory_name,
    key: `CATALOG-${catalog.id}`,
    icon: <FolderOutlined />,
    children: typeNodes,
    data: catalog,
    directoryId: catalog.id
  };
  return node;
}

function listReports(node) {
  const reports = [];
  if (_.startsWith(node.key, "REPORT-")) {
    reports.push(node.data);
  }
  if (node.children) {
    for (const c of node.children) {
      const subReports = listReports(c);
      subReports.forEach(rr => reports.push(rr))
    }
  }
  return reports;
}

class ReportTree extends React.Component {
  constructor(props) {
    super(props);

    this.onExpand = this.onExpand.bind(this);
    this.onSelect = this.onSelect.bind(this);
    this.onDoubleClick = this.onDoubleClick.bind(this);
    this.showCreateDirDialog = this.showCreateDirDialog.bind(this);
    this.hideCreateDirDialog = this.hideCreateDirDialog.bind(this);
    this.onReportDirSaved = this.onReportDirSaved.bind(this);
    this.showCreateFileDialog = this.showCreateFileDialog.bind(this);
    this.hideCreateFileDialog = this.hideCreateFileDialog.bind(this);
    this.onReportFileSaved = this.onReportFileSaved.bind(this);
    this.deleteNode = this.deleteNode.bind(this);
    this.editNode = this.editNode.bind(this);

    this.state = {
      reportTreeLoading: true,
      reportTree: [],
      expandedKeys: [],
      selectedNode: null,
      reportDirDialogEdit: false,
      reportDirDialogOpen: false,
      reportFileDialogEdit: false,
      reportFileDialogOpen: false,
    };
  }

  componentDidMount() {
    this.reloadReportTree();
  }

  reloadReportTree() {
    this.setState({ reportTreeLoading: true });
    SparkChannel().then(channel => {
      return channel.request_get_report_list();
    }).then(resp => {
      // console.log('Got tree data', resp);
      const reportDirectory = resp.data.report_directory;
      const treeData = reportDirectory.map(catalog => {
        return buildTreeNode(catalog);
      });

      this.setState({
        reportTreeLoading: false,
        reportTree: treeData
      });
    }).catch((err) => {
      console.log('Got tree fail', err);
      this.setState({ reportTreeLoading: false });
      message.error('加载目录树失败');
    });
  }

  onExpand(expandedKeysValue) {
    this.setState({ expandedKeys: expandedKeysValue })
  }

  onSelect(selectedKeysValue, info) {
    // console.log('onSelect', selectedKeysValue, info);
    const node = info.node;
    this.setState({ selectedNode: node });
  }
  onDoubleClick(node) {
    if (_.startsWith(node.key, "REPORT-")) {
      const report = node.data;
      EE.emit('open-workbook', report);
    } else {
      // 切换展开状态
      this.setState((state) => {
        const expandedKeys = state.expandedKeys;
        const index = expandedKeys.indexOf(node.key);
        let result;
        if (index === -1) {
          result = expandedKeys.concat(node.key);
        } else {
          result = expandedKeys.filter(k => k !== node.key);
        }
        return { expandedKeys: result };
      });
    }
  }

  showCreateDirDialog() {
    this.setState({
      reportDirDialogEdit: false,
      reportDirDialogOpen: true
    });
  }
  showEditDirDialog() {
    this.setState({
      reportDirDialogEdit: true,
      reportDirDialogOpen: true
    });
  }
  hideCreateDirDialog() {
    this.setState({ reportDirDialogOpen: false });
  }
  onReportDirSaved(edit, resp) {
    this.setState({ reportDirDialogOpen: false });
    // const node = buildTreeNode(catalog);
    // this.setState((state, props) => ({
    //     reportTree: state.reportTree.concat(node)
    // }));
    this.reloadReportTree();
  }

  showCreateFileDialog() {
    this.setState({
      reportFileDialogEdit: false,
      reportFileDialogOpen: true
    });
  }
  showEditFileDialog() {
    this.setState({
      reportFileDialogEdit: true,
      reportFileDialogOpen: true
    });
  }
  hideCreateFileDialog() {
    this.setState({ reportFileDialogOpen: false });
  };
  onReportFileSaved(edit, resp) {
    this.setState({ reportFileDialogOpen: false });
    this.reloadReportTree();
  }

  editNode() {
    const node = this.state.selectedNode;
    if (!node) {
      MyModal.warning({ content: '请选择目录或者报表模板' });
    } else if (_.startsWith(node.key, "CATALOG-")) {
      this.showEditDirDialog();
    } else if (_.startsWith(node.key, "REPORT-")) {
      this.showEditFileDialog();
    } else {
      MyModal.warning({ content: '请选择目录或者报表模板' });
    }
  }
  deleteNode() {
    const node = this.state.selectedNode;
    const self = this;
    if (!node) {
      MyModal.warning({ content: '请选择目录或者报表模板' });
    } else if (_.startsWith(node.key, "CATALOG-")) {
      MyModal.confirm({
        content: `确定删除“${node.title}”及其下的报表模板`,
        async onOk() {
          try {
            const channel = await SparkChannel();
            const resp = await channel.request_delete_directory({ id: node.directoryId });
            console.log('delete directory success.', resp);

            const reports = listReports(node);
            reports.forEach(report => {
              EE.emit('delete-workbook', report);
            });
            self.reloadReportTree();
          } catch (err) {
            console.log('Delete dir fail', err);
            message.error('删除失败');
          }
        },
      });
    } else if (_.startsWith(node.key, "REPORT-")) {
      const report = node.data;
      MyModal.confirm({
        content: `确定删除“${node.title}”`,
        async onOk() {
          try {
            const channel = await SparkChannel();
            const resp = await channel.request_delete_report({ id: report.id });
            console.log('delete report success.', resp);

            EE.emit('delete-workbook', report);

            self.reloadReportTree();
          } catch (err) {
            console.log('Delete dir fail', err);
            message.error('删除失败');
          }
        },
      });
    } else {
      MyModal.warning({ content: '请选择目录或者报表模板' });
    }
  }

  render() {
    const { edit } = this.props;
    const state = this.state;
    const directorys = this.state.reportTree.map(node => node.data);
    const node = this.state.selectedNode;
    const selectedKeys = node ? [node.key] : [];

    let selectedDirectory = null;
    if (state.reportDirDialogEdit && _.startsWith(node.key, "CATALOG-")) {
      selectedDirectory = node.data;
    }

    let selectedReport = null;
    if (state.reportFileDialogEdit) {
      if (_.startsWith(node.key, "REPORT-")) {
        selectedReport = node.data;
      }
    } else {
      selectedReport = {
        "directory_id": node && node.directoryId,
        "report_type": node && node.reportType,
      };
    }


    return (
      <>
        {edit &&
          <div className='tree-toolbar'>
            <Space>
              <Tooltip title="新建目录">
                <Button icon={<FolderAddOutlined />} onClick={this.showCreateDirDialog} />
              </Tooltip>
              <Tooltip title="新建文件">
                <Button icon={<FileAddOutlined />} onClick={this.showCreateFileDialog} />
              </Tooltip>
              <Tooltip title="删除目录/文件">
                <Button icon={<DeleteOutlined />} onClick={this.deleteNode} />
              </Tooltip>
              <Tooltip title="编辑">
                <Button icon={<EditOutlined />} onClick={this.editNode} />
              </Tooltip>
            </Space>
          </div>}

        <Spin spinning={this.state.reportTreeLoading}>
          <MyTree
            showIcon
            defaultExpandAll
            expandedKeys={state.expandedKeys}
            onExpand={this.onExpand}
            onSelect={this.onSelect}
            onDoubleClick={this.onDoubleClick}
            treeData={state.reportTree}
            selectedKeys={selectedKeys}
          />
        </Spin>

        {/* Dialog需要重新挂载，否则initialValues无法刷新 */}
        {state.reportDirDialogOpen &&
          <ReportDirDialog
            edit={state.reportDirDialogEdit}
            directory={selectedDirectory}
            open={state.reportDirDialogOpen}
            onCancel={this.hideCreateDirDialog}
            onDirSaved={this.onReportDirSaved} />}
        {state.reportFileDialogOpen &&
          <ReportFileDialog
            edit={state.reportFileDialogEdit}
            directorys={directorys}
            report={selectedReport}
            open={state.reportFileDialogOpen}
            onCancel={this.hideCreateFileDialog}
            onFileSaved={this.onReportFileSaved} />}
      </>
    )
  }
}

export default ReportTree